import BankingManagement.BankingService;
import RestaurantManagement.Meal;
import RestaurantManagement.RestaurantService;
import ShapeManagement.ShapeService;
import ZooManagement.Item;
import ZooManagement.Zoo;
import ZooManagement.Animal;
import ZooManagement.ZooService;
import ShapeManagement.bounceboxframework.Shape;
import java.util.List;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.io.File;

public class GUI extends JFrame {
    private CardLayout cardLayout;
    private JPanel mainPanel;
    private RestaurantService restaurantService;
    private ShapeService shapeService;
    private BankingService bankingService;
    private ZooService zooService;
    private ArrayList<Shape> shapes;

    public GUI() {
        super("Integrated Management System");
        restaurantService = new RestaurantService();
        shapeService = new ShapeService();
        bankingService = new BankingService();
        zooService = new ZooService();
        shapes = null;

        cardLayout = new CardLayout();
        mainPanel = new JPanel(cardLayout);

        JPanel dashboardPanel = createDashboardPanel();
        mainPanel.add(dashboardPanel, "dashboard");

        JPanel restaurantPanel = createRestaurantPanel();
        mainPanel.add(restaurantPanel, "restaurant");

        JPanel shapePanel = createShapePanel();
        mainPanel.add(shapePanel, "shape");

        JPanel bankingPanel = createBankingPanel();
        mainPanel.add(bankingPanel, "banking");

        JPanel zooPanel = createZooPanel();
        mainPanel.add(zooPanel, "zoo");

        add(mainPanel);
        cardLayout.show(mainPanel, "dashboard");

        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    private JPanel createDashboardPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        JLabel titleLabel = new JLabel("Integrated Management System", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 24));
        panel.add(titleLabel, BorderLayout.NORTH);

        JPanel buttonPanel = new JPanel(new GridLayout(2, 2, 10, 10));
        JButton restaurantButton = new JButton("Restaurant Management");
        restaurantButton.addActionListener(e -> cardLayout.show(mainPanel, "restaurant"));
        buttonPanel.add(restaurantButton);

        JButton shapeButton = new JButton("Shape Parsing & Analysis");
        shapeButton.addActionListener(e -> cardLayout.show(mainPanel, "shape"));
        buttonPanel.add(shapeButton);

        JButton bankingButton = new JButton("Banking Management");
        bankingButton.addActionListener(e -> cardLayout.show(mainPanel, "banking"));
        buttonPanel.add(bankingButton);

        JButton zooButton = new JButton("Zoo Management");
        zooButton.addActionListener(e -> cardLayout.show(mainPanel, "zoo"));
        buttonPanel.add(zooButton);

        panel.add(buttonPanel, BorderLayout.CENTER);
        return panel;
    }

    private JPanel createRestaurantPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        JLabel titleLabel = new JLabel("Restaurant Management", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 20));
        panel.add(titleLabel, BorderLayout.NORTH);

        JPanel operationsPanel = new JPanel();
        operationsPanel.setLayout(new BoxLayout(operationsPanel, BoxLayout.Y_AXIS));

        // Add Bank Account Section
        JPanel bankAccountPanel = new JPanel(new FlowLayout());
        bankAccountPanel.setBorder(BorderFactory.createTitledBorder("Bank Account"));
        JTextField accountField = new JTextField(15);
        bankAccountPanel.add(new JLabel("Account Number:"));
        bankAccountPanel.add(accountField);

        JLabel balanceLabel = new JLabel("Balance: -");
        bankAccountPanel.add(balanceLabel);

        JButton checkBalanceButton = new JButton("Check Balance");
        checkBalanceButton.addActionListener(e -> {
            String account = accountField.getText().trim();
            if (account.isEmpty()) {
                JOptionPane.showMessageDialog(this, "Please enter an account number.");
                return;
            }
            double balance = bankingService.getBalance(account);
            if (balance >= 0) {
                balanceLabel.setText(String.format("Balance: RMB %.2f", balance));
            } else {
                balanceLabel.setText("Account not found");
            }
        });
        bankAccountPanel.add(checkBalanceButton);
        operationsPanel.add(bankAccountPanel);

        // Add Ingredient Section
        JPanel addIngredientPanel = new JPanel(new FlowLayout());
        addIngredientPanel.setBorder(BorderFactory.createTitledBorder("Add Ingredient"));
        JTextField nameField = new JTextField(10);
        addIngredientPanel.add(new JLabel("Name:"));
        addIngredientPanel.add(nameField);
        JTextField priceField = new JTextField(5);
        addIngredientPanel.add(new JLabel("Price:"));
        addIngredientPanel.add(priceField);
        JButton addButton = new JButton("Add");
        addButton.addActionListener(e -> {
            String name = nameField.getText().trim();
            String priceText = priceField.getText().trim();
            if (name.isEmpty() || priceText.isEmpty()) {
                JOptionPane.showMessageDialog(this, "Name and price cannot be empty.");
                return;
            }
            try {
                double price = Double.parseDouble(priceText);
                if (price < 0) {
                    JOptionPane.showMessageDialog(this, "Price must be a positive number.");
                    return;
                }
                restaurantService.addIngredient(name, price);
                JOptionPane.showMessageDialog(this, "Ingredient '" + name + "' added successfully.");
                nameField.setText("");
                priceField.setText("");
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "Invalid price format.");
            }
        });
        addIngredientPanel.add(addButton);
        operationsPanel.add(addIngredientPanel);

        // Create Meal Section
        JPanel createMealPanel = new JPanel(new FlowLayout());
        createMealPanel.setBorder(BorderFactory.createTitledBorder("Create Meal"));
        JTextField mealNameField = new JTextField(10);
        createMealPanel.add(new JLabel("Meal Name:"));
        createMealPanel.add(mealNameField);
        JTextField ingredientsField = new JTextField(20);
        createMealPanel.add(new JLabel("Ingredients (comma-separated):"));
        createMealPanel.add(ingredientsField);
        JButton createButton = new JButton("Create");
        createButton.addActionListener(e -> {
            String mealName = mealNameField.getText();
            String ingredientsStr = ingredientsField.getText();
            String[] ingredientsArray = ingredientsStr.split(",");
            ArrayList<String> ingredients = new ArrayList<>();
            for (String ing : ingredientsArray) {
                ingredients.add(ing.trim());
            }
            restaurantService.createMeal(mealName, ingredients);
            JOptionPane.showMessageDialog(this, "Meal created successfully.");
        });
        createMealPanel.add(createButton);
        operationsPanel.add(createMealPanel);

        // Place Order Section
        JPanel placeOrderPanel = new JPanel(new FlowLayout());
        placeOrderPanel.setBorder(BorderFactory.createTitledBorder("Place Order"));
        JTextArea orderTextArea = new JTextArea(5, 20);
        placeOrderPanel.add(new JLabel("Meals (meal quantity, separated by newline, e.g., 'Burger 2'):"));
        placeOrderPanel.add(new JScrollPane(orderTextArea));
        JButton placeOrderButton = new JButton("Place Order & Pay");
        placeOrderButton.addActionListener(e -> {
            String orderText = orderTextArea.getText().trim();
            String accountNumber = accountField.getText().trim();

            if (orderText.isEmpty()) {
                JOptionPane.showMessageDialog(this, "Order cannot be empty.");
                return;
            }

            if (accountNumber.isEmpty()) {
                JOptionPane.showMessageDialog(this, "Please enter a bank account number.");
                return;
            }

            String[] lines = orderText.split("\n");
            HashMap<String, Integer> mealQuantities = new HashMap<>();
            for (String line : lines) {
                line = line.trim();
                if (line.isEmpty()) continue;

                String[] parts = line.split("\\s+");
                if (parts.length < 2) {
                    JOptionPane.showMessageDialog(this, "Invalid format in order: '" + line + "'. Expected 'meal quantity'.");
                    return;
                }

                String meal = parts[0].trim();
                String quantityStr = parts[1].trim();
                try {
                    int quantity = Integer.parseInt(quantityStr);
                    if (quantity <= 0) {
                        JOptionPane.showMessageDialog(this, "Quantity must be a positive integer: '" + line + "'.");
                        return;
                    }
                    mealQuantities.put(meal, quantity);
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(this, "Invalid quantity in order: '" + quantityStr + "'. Must be an integer.");
                    return;
                }
            }

            if (mealQuantities.isEmpty()) {
                JOptionPane.showMessageDialog(this, "No valid meals in order.");
                return;
            }

            // Calculate total bill
            double totalBill = 0;
            for (String mealName : mealQuantities.keySet()) {
                int quantity = mealQuantities.get(mealName);
                Meal meal = restaurantService.findMealByName(mealName);
                if (meal != null) {
                    totalBill += meal.getPrice() * quantity;
                }
            }

            // Check if account has sufficient balance
            double currentBalance = bankingService.getBalance(accountNumber);
            if (currentBalance < totalBill) {
                JOptionPane.showMessageDialog(this,
                        String.format("Insufficient funds. Required: RMB %.2f, Available: RMB %.2f",
                                totalBill, currentBalance));
                return;
            }

            // Process payment
            boolean paymentSuccess = bankingService.withdraw(accountNumber, totalBill);
            if (!paymentSuccess) {
                JOptionPane.showMessageDialog(this, "Payment processing failed.");
                return;
            }

            // Place the order
            String orderId = restaurantService.placeOrder(mealQuantities);

            // Update balance display
            double newBalance = bankingService.getBalance(accountNumber);
            balanceLabel.setText(String.format("Balance: RMB %.2f", newBalance));

            JOptionPane.showMessageDialog(this,
                    String.format("Order placed and paid successfully!\nOrder ID: %s\nTotal: RMB %.2f\nNew Balance: RMB %.2f",
                            orderId, totalBill, newBalance));

            orderTextArea.setText("");
        });
        placeOrderPanel.add(placeOrderButton);
        operationsPanel.add(placeOrderPanel);

        // Calculate Bill Section
        JPanel calculateBillPanel = new JPanel(new FlowLayout());
        calculateBillPanel.setBorder(BorderFactory.createTitledBorder("Calculate Bill"));
        JTextField orderIdField = new JTextField(10);
        calculateBillPanel.add(new JLabel("Order ID:"));
        calculateBillPanel.add(orderIdField);
        JButton calculateButton = new JButton("Calculate");
        calculateButton.addActionListener(e -> {
            String orderId = orderIdField.getText();
            double bill = restaurantService.calculateBill(orderId);
            JOptionPane.showMessageDialog(this, "The bill for order " + orderId + " is: " + bill);
        });
        calculateBillPanel.add(calculateButton);
        operationsPanel.add(calculateBillPanel);

        panel.add(operationsPanel, BorderLayout.CENTER);

        JButton backButton = new JButton("Back to Dashboard");
        backButton.addActionListener(e -> cardLayout.show(mainPanel, "dashboard"));
        JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        bottomPanel.add(backButton);
        panel.add(bottomPanel, BorderLayout.SOUTH);

        return panel;
    }

    private JPanel createShapePanel() {
        JPanel panel = new JPanel(new BorderLayout());
        JLabel titleLabel = new JLabel("Shape Parsing & Analysis", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 20));
        panel.add(titleLabel, BorderLayout.NORTH);

        // Main content panel with vertical layout for sections
        JPanel contentPanel = new JPanel();
        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
        contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // Add padding

        // Parse File Section
        JPanel parseFilePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel parseFileLabel = new JLabel("Parse File");
        parseFileLabel.setFont(new Font("Serif", Font.BOLD, 14));
        parseFilePanel.add(parseFileLabel);

        JButton parseFileButton = new JButton("Parse File");
        parseFileButton.setPreferredSize(new Dimension(100, 30)); // Consistent button size
        parseFileButton.addActionListener(e -> {
            JFileChooser fileChooser = new JFileChooser();
            int result = fileChooser.showOpenDialog(this);
            if (result == JFileChooser.APPROVE_OPTION) {
                String filePath = fileChooser.getSelectedFile().getAbsolutePath();
                try {
                    shapes = shapeService.parseFile(filePath);
                    JOptionPane.showMessageDialog(this, "File parsed successfully. " + shapes.size() + " shapes loaded.");
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(this, "Error parsing file: " + ex.getMessage());
                }
            }
        });
        parseFilePanel.add(parseFileButton);
        contentPanel.add(parseFilePanel);
        contentPanel.add(Box.createVerticalStrut(10)); // Spacing between sections

        // Count by Type Section
        JPanel countByTypePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel countByTypeLabel = new JLabel("Count by Type");
        countByTypeLabel.setFont(new Font("Serif", Font.BOLD, 14));
        countByTypePanel.add(countByTypeLabel);

        JButton countByTypeButton = new JButton("Count");
        countByTypeButton.setPreferredSize(new Dimension(100, 30));
        countByTypeButton.addActionListener(e -> {
            if (shapes == null) {
                JOptionPane.showMessageDialog(this, "Please parse a file first.");
                return;
            }
            HashMap<String, Integer> counts = shapeService.countByType(shapes);
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, Integer> entry : counts.entrySet()) {
                sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
            }
            JOptionPane.showMessageDialog(this, sb.toString());
        });
        countByTypePanel.add(countByTypeButton);
        contentPanel.add(countByTypePanel);
        contentPanel.add(Box.createVerticalStrut(10));

        // Total Area Section
        JPanel totalAreaPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel totalAreaLabel = new JLabel("Total Area");
        totalAreaLabel.setFont(new Font("Serif", Font.BOLD, 14));
        totalAreaPanel.add(totalAreaLabel);

        JButton totalAreaButton = new JButton("Calculate");
        totalAreaButton.setPreferredSize(new Dimension(100, 30));
        totalAreaButton.addActionListener(e -> {
            if (shapes == null) {
                JOptionPane.showMessageDialog(this, "Please parse a file first.");
                return;
            }
            double area = shapeService.totalArea(shapes);
            JOptionPane.showMessageDialog(this, "Total area: " + area);
        });
        totalAreaPanel.add(totalAreaButton);
        contentPanel.add(totalAreaPanel);
        contentPanel.add(Box.createVerticalStrut(10));

        // Display Shapes Section
        JPanel displayShapesPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel displayShapesLabel = new JLabel("Display Shapes");
        displayShapesLabel.setFont(new Font("Serif", Font.BOLD, 14));
        displayShapesPanel.add(displayShapesLabel);

        JButton displayShapesButton = new JButton("Display");
        displayShapesButton.setPreferredSize(new Dimension(100, 30));
        displayShapesButton.addActionListener(e -> {
            if (shapes == null) {
                JOptionPane.showMessageDialog(this, "Please parse a file first.");
                return;
            }
            shapeService.displayShapes(shapes);
        });
        displayShapesPanel.add(displayShapesButton);
        contentPanel.add(displayShapesPanel);

        panel.add(contentPanel, BorderLayout.CENTER);

        // Back button at the bottom
        JButton backButton = new JButton("Back to Dashboard");
        backButton.setPreferredSize(new Dimension(150, 30));
        backButton.addActionListener(e -> cardLayout.show(mainPanel, "dashboard"));
        JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        bottomPanel.add(backButton);
        panel.add(bottomPanel, BorderLayout.SOUTH);

        return panel;
    }

    private JPanel createBankingPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        JLabel titleLabel = new JLabel("Banking Management", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 20));
        panel.add(titleLabel, BorderLayout.NORTH);

        // Main content panel with tabs
        JTabbedPane tabbedPane = new JTabbedPane();

        // Account Management Tab
        tabbedPane.addTab("Account Management", createAccountManagementPanel());

        // Transactions Tab
        tabbedPane.addTab("Transactions", createTransactionsPanel());

        // Task Management Tab
        tabbedPane.addTab("Task Management", createTaskManagementPanel());

        panel.add(tabbedPane, BorderLayout.CENTER);

        // Back button
        JButton backButton = new JButton("Back to Dashboard");
        backButton.addActionListener(e -> cardLayout.show(mainPanel, "dashboard"));
        JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        bottomPanel.add(backButton);
        panel.add(bottomPanel, BorderLayout.SOUTH);

        return panel;
    }

    private JPanel createAccountManagementPanel() {
        JPanel panel = new JPanel(new BorderLayout());

        // Account creation section
        JPanel createPanel = new JPanel(new GridLayout(4, 2, 5, 5));
        createPanel.setBorder(BorderFactory.createTitledBorder("Create Account"));

        JTextField accountNumberField = new JTextField();
        JTextField initialBalanceField = new JTextField();
        JTextField interestRateField = new JTextField();

        createPanel.add(new JLabel("Account Number:"));
        createPanel.add(accountNumberField);
        createPanel.add(new JLabel("Initial Balance:"));
        createPanel.add(initialBalanceField);
        createPanel.add(new JLabel("Interest Rate (%):"));
        createPanel.add(interestRateField);

        JButton createButton = new JButton("Create Account");
        createButton.addActionListener(e -> {
            try {
                String accountNumber = accountNumberField.getText();
                double balance = Double.parseDouble(initialBalanceField.getText());
                double rate = Double.parseDouble(interestRateField.getText());

                bankingService.createAccount(accountNumber, balance, rate);
                JOptionPane.showMessageDialog(this, "Account created successfully!");

                // Clear fields
                accountNumberField.setText("");
                initialBalanceField.setText("");
                interestRateField.setText("");

            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "Invalid number format", "Error", JOptionPane.ERROR_MESSAGE);
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(this, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        });

        createPanel.add(new JLabel());
        createPanel.add(createButton);

        // Account details section
        JPanel detailsPanel = new JPanel(new BorderLayout());
        detailsPanel.setBorder(BorderFactory.createTitledBorder("Account Details"));

        JComboBox<String> accountSelector = new JComboBox<>();
        JTextArea detailsArea = new JTextArea(5, 20);
        detailsArea.setEditable(false);

        JButton refreshButton = new JButton("Refresh Accounts");
        refreshButton.addActionListener(e -> {
            accountSelector.removeAllItems();
            bankingService.listAllAccounts().forEach(accountSelector::addItem);
        });

        JButton viewButton = new JButton("View Details");
        viewButton.addActionListener(e -> {
            String account = (String)accountSelector.getSelectedItem();
            if (account != null) {
                detailsArea.setText(bankingService.getAccountDetails(account));
            }
        });

        JPanel detailsButtonPanel = new JPanel();
        detailsButtonPanel.add(refreshButton);
        detailsButtonPanel.add(viewButton);

        detailsPanel.add(accountSelector, BorderLayout.NORTH);
        detailsPanel.add(new JScrollPane(detailsArea), BorderLayout.CENTER);
        detailsPanel.add(detailsButtonPanel, BorderLayout.SOUTH);

        // Add sections to main panel
        panel.add(createPanel, BorderLayout.NORTH);
        panel.add(detailsPanel, BorderLayout.CENTER);

        return panel;
    }

    private JPanel createTransactionsPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        JLabel titleLabel = new JLabel("Transactions", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 16));
        panel.add(titleLabel, BorderLayout.NORTH);

        // Deposit section
        JPanel depositPanel = new JPanel(new GridLayout(3, 2, 5, 5));
        depositPanel.setBorder(BorderFactory.createTitledBorder("Deposit"));

        JTextField depositAccountField = new JTextField(20);
        JTextField depositAmountField = new JTextField(10);

        depositPanel.add(new JLabel("Account Number:"));
        depositPanel.add(depositAccountField);
        depositPanel.add(new JLabel("Amount:"));
        depositPanel.add(depositAmountField);

        JButton depositButton = new JButton("Deposit");
        depositButton.addActionListener(e -> {
            try {
                String account = depositAccountField.getText();
                double amount = Double.parseDouble(depositAmountField.getText());

                if (bankingService.deposit(account, amount)) {
                    JOptionPane.showMessageDialog(this, "Deposit successful!");
                    depositAccountField.setText("");
                    depositAmountField.setText("");
                } else {
                    JOptionPane.showMessageDialog(this, "Deposit failed", "Error", JOptionPane.ERROR_MESSAGE);
                }
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "Invalid amount", "Error", JOptionPane.ERROR_MESSAGE);
            }
        });

        depositPanel.add(new JLabel());
        depositPanel.add(depositButton);

        // Withdrawal section
        JPanel withdrawPanel = new JPanel(new GridLayout(3, 2, 5, 5));
        withdrawPanel.setBorder(BorderFactory.createTitledBorder("Withdraw"));

        JTextField withdrawAccountField = new JTextField(20);
        JTextField withdrawAmountField = new JTextField(10);

        withdrawPanel.add(new JLabel("Account Number:"));
        withdrawPanel.add(withdrawAccountField);
        withdrawPanel.add(new JLabel("Amount:"));
        withdrawPanel.add(withdrawAmountField);

        JButton withdrawButton = new JButton("Withdraw");
        withdrawButton.addActionListener(e -> {
            try {
                String account = withdrawAccountField.getText();
                double amount = Double.parseDouble(withdrawAmountField.getText());

                if (bankingService.withdraw(account, amount)) {
                    JOptionPane.showMessageDialog(this, "Withdrawal successful!");
                    withdrawAccountField.setText("");
                    withdrawAmountField.setText("");
                } else {
                    JOptionPane.showMessageDialog(this, "Withdrawal failed", "Error", JOptionPane.ERROR_MESSAGE);
                }
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "Invalid amount", "Error", JOptionPane.ERROR_MESSAGE);
            }
        });

        withdrawPanel.add(new JLabel());
        withdrawPanel.add(withdrawButton);


        JPanel balancePanel = new JPanel(new BorderLayout());
        balancePanel.setBorder(BorderFactory.createTitledBorder("Check Balance"));

        JTextField balanceAccountField = new JTextField(25);  // Extend the input box
        JButton balanceButton = new JButton("Check Balance");
        JLabel balanceResultLabel = new JLabel("Balance: ");

        balanceButton.addActionListener(e -> {
            String account = balanceAccountField.getText();
            double balance = bankingService.getBalance(account);

            if (balance >= 0) {
                balanceResultLabel.setText(String.format("Balance: RMB %.2f", balance));
            } else {
                balanceResultLabel.setText("Account not found");
            }
        });

        JPanel balanceInputPanel = new JPanel(new FlowLayout());
        balanceInputPanel.add(new JLabel("Account Number:"));
        balanceInputPanel.add(balanceAccountField);
        balanceInputPanel.add(balanceButton);

        balancePanel.add(balanceInputPanel, BorderLayout.NORTH);
        balancePanel.add(balanceResultLabel, BorderLayout.CENTER);

        // Add sections to main panel
        JPanel transactionSections = new JPanel();
        transactionSections.setLayout(new BoxLayout(transactionSections, BoxLayout.Y_AXIS));
        transactionSections.add(depositPanel);
        transactionSections.add(withdrawPanel);
        transactionSections.add(balancePanel);

        panel.add(transactionSections, BorderLayout.CENTER);

        return panel;
    }

    private JPanel createTaskManagementPanel() {
        JPanel panel = new JPanel(new BorderLayout());

        // Task lists
        JPanel listsPanel = new JPanel(new GridLayout(1, 2));

        DefaultListModel<String> highPriorityModel = new DefaultListModel<>();
        JList<String> highPriorityList = new JList<>(highPriorityModel);
        highPriorityList.setBorder(BorderFactory.createTitledBorder("High Priority Tasks"));

        DefaultListModel<String> lowPriorityModel = new DefaultListModel<>();
        JList<String> lowPriorityList = new JList<>(lowPriorityModel);
        lowPriorityList.setBorder(BorderFactory.createTitledBorder("Low Priority Tasks"));

        listsPanel.add(new JScrollPane(highPriorityList));
        listsPanel.add(new JScrollPane(lowPriorityList));

        // Task controls
        JPanel controlPanel = new JPanel(new FlowLayout());

        JButton refreshButton = new JButton("Refresh Tasks");
        refreshButton.addActionListener(e -> {
            // Clear the current model
            highPriorityModel.clear();
            lowPriorityModel.clear();

            // Obtain the task list and update the model
            bankingService.listHighPriorityTasks().forEach(highPriorityModel::addElement);
            bankingService.listLowPriorityTasks().forEach(lowPriorityModel::addElement);
        });

        JButton removeButton = new JButton("Remove Selected");
        removeButton.addActionListener(e -> {
            if (!highPriorityList.isSelectionEmpty()) {
                int index = highPriorityList.getSelectedIndex();
                bankingService.removeTask("high", index);
            } else if (!lowPriorityList.isSelectionEmpty()) {
                int index = lowPriorityList.getSelectedIndex();
                bankingService.removeTask("low", index);
            }
            refreshButton.doClick();
        });

        JButton changePriorityButton = new JButton("Change Priority");
        changePriorityButton.addActionListener(e -> {
            try {
                if (!highPriorityList.isSelectionEmpty()) {
                    int index = highPriorityList.getSelectedIndex();
                    bankingService.changeTaskPriority("high", index);
                } else if (!lowPriorityList.isSelectionEmpty()) {
                    int index = lowPriorityList.getSelectedIndex();
                    bankingService.changeTaskPriority("low", index);
                } else {
                    JOptionPane.showMessageDialog(panel, "Please select a task to change priority.");
                    return;
                }
                refreshButton.doClick(); // Refresh the list
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(panel, "Error changing priority: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        });

        controlPanel.add(refreshButton);
        controlPanel.add(removeButton);
        controlPanel.add(changePriorityButton);

        // Manual task addition
        JPanel addTaskPanel = new JPanel(new BorderLayout());
        JTextField taskField = new JTextField();
        JButton addButton = new JButton("Add Task");

        addButton.addActionListener(e -> {
            String task = taskField.getText().trim();
            if (!task.isEmpty()) {
                bankingService.addManualTask(task);
                taskField.setText("");
                refreshButton.doClick(); // Refresh the list
            } else {
                JOptionPane.showMessageDialog(panel, "Task name cannot be empty.");
            }
        });

        addTaskPanel.add(new JLabel("Add New Task:"), BorderLayout.WEST);
        addTaskPanel.add(taskField, BorderLayout.CENTER);
        addTaskPanel.add(addButton, BorderLayout.EAST);

        // Add components to main panel
        panel.add(listsPanel, BorderLayout.CENTER);
        panel.add(controlPanel, BorderLayout.SOUTH);
        panel.add(addTaskPanel, BorderLayout.NORTH);

        // Initial refresh
        refreshButton.doClick();

        return panel;
    }

private JPanel createZooPanel() {
    JPanel panel = new JPanel(new BorderLayout());
    JLabel titleLabel = new JLabel("Zoo Management", SwingConstants.CENTER);
    titleLabel.setFont(new Font("Serif", Font.BOLD, 20));
    panel.add(titleLabel, BorderLayout.NORTH);

    // Create the main content panel and use the vertical layout
    JPanel mainContentPanel = new JPanel();
    mainContentPanel.setLayout(new BoxLayout(mainContentPanel, BoxLayout.Y_AXIS));

    // Add the operation panel
    JPanel operationsPanel = new JPanel();
    operationsPanel.setLayout(new BoxLayout(operationsPanel, BoxLayout.Y_AXIS));
    operationsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

    // Add Animal Section
    JPanel addAnimalPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    addAnimalPanel.setBorder(BorderFactory.createTitledBorder("Add Animal"));
    JTextField animalNameField = new JTextField(10);
    addAnimalPanel.add(new JLabel("Name:"));
    addAnimalPanel.add(animalNameField);
    JTextField speciesField = new JTextField(10);
    addAnimalPanel.add(new JLabel("Species:"));
    addAnimalPanel.add(speciesField);
    JTextField ageField = new JTextField(5);
    addAnimalPanel.add(new JLabel("Age:"));
    addAnimalPanel.add(ageField);
    JComboBox<String> zooComboBox = new JComboBox<>(new String[]{"Southern-Zone", "Northern-Zone"});
    addAnimalPanel.add(new JLabel("Zoo:"));
    addAnimalPanel.add(zooComboBox);
    JButton addButton = new JButton("Add");
    addButton.addActionListener(e -> {
        String name = animalNameField.getText().trim();
        String species = speciesField.getText().trim();
        String ageText = ageField.getText().trim();
        String zooName = (String) zooComboBox.getSelectedItem();
        if (name.isEmpty() || species.isEmpty() || ageText.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Name, species, and age cannot be empty.");
            return;
        }
        try {
            int age = Integer.parseInt(ageText);
            if (age < 0) {
                JOptionPane.showMessageDialog(this, "Age must be a positive number.");
                return;
            }
            boolean success = zooService.addAnimal(zooName, name, species, age);
            if (success) {
                JOptionPane.showMessageDialog(this, "Animal '" + name + "' added successfully to " + zooName + " Zoo.");
                animalNameField.setText("");
                speciesField.setText("");
                ageField.setText("");
            } else {
                JOptionPane.showMessageDialog(this, "Failed to add animal. Zoo may be full or invalid.");
            }
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "Invalid age format.");
        }
    });
    addAnimalPanel.add(addButton);
    operationsPanel.add(addAnimalPanel);
    operationsPanel.add(Box.createVerticalStrut(10));

    // Move Animal Section
    JPanel moveAnimalPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    moveAnimalPanel.setBorder(BorderFactory.createTitledBorder("Move Animal"));
    JTextField moveAnimalNameField = new JTextField(10);
    moveAnimalPanel.add(new JLabel("Animal Name:"));
    moveAnimalPanel.add(moveAnimalNameField);
    JComboBox<String> fromZooComboBox = new JComboBox<>(new String[]{"Southern-Zone", "Northern-Zone"});
    moveAnimalPanel.add(new JLabel("From Zoo:"));
    moveAnimalPanel.add(fromZooComboBox);
    JComboBox<String> toZooComboBox = new JComboBox<>(new String[]{"Southern-Zone", "Northern-Zone"});
    moveAnimalPanel.add(new JLabel("To Zoo:"));
    moveAnimalPanel.add(toZooComboBox);
    JTextField vehiclePriceField = new JTextField(5);
    moveAnimalPanel.add(new JLabel("Vehicle Price:"));
    moveAnimalPanel.add(vehiclePriceField);
    JTextField fuelPriceField = new JTextField(5);
    moveAnimalPanel.add(new JLabel("Fuel Price:"));
    moveAnimalPanel.add(fuelPriceField);
    JTextField caretakersField = new JTextField(15);
    moveAnimalPanel.add(new JLabel("Caretakers (comma-separated):"));
    moveAnimalPanel.add(caretakersField);
    JButton moveButton = new JButton("Move");
    moveButton.addActionListener(e -> {
        String animalName = moveAnimalNameField.getText().trim();
        String fromZoo = (String) fromZooComboBox.getSelectedItem();
        String toZoo = (String) toZooComboBox.getSelectedItem();
        String vehiclePriceText = vehiclePriceField.getText().trim();
        String fuelPriceText = fuelPriceField.getText().trim();
        String caretakersText = caretakersField.getText().trim();
        if (animalName.isEmpty() || fromZoo.equals(toZoo) || vehiclePriceText.isEmpty() || fuelPriceText.isEmpty() || caretakersText.isEmpty()) {
            JOptionPane.showMessageDialog(this, "All fields must be filled, and source zoo must differ from destination zoo.");
            return;
        }
        try {
            double vehiclePrice = Double.parseDouble(vehiclePriceText);
            double fuelPrice = Double.parseDouble(fuelPriceText);
            if (vehiclePrice < 0 || fuelPrice < 0) {
                JOptionPane.showMessageDialog(this, "Prices must be positive numbers.");
                return;
            }
            String[] caretakersArray = caretakersText.split(",");
            List<String> caretakers = new ArrayList<>();
            for (String caretaker : caretakersArray) {
                String trimmedCaretaker = caretaker.trim();
                if (!trimmedCaretaker.isEmpty()) {
                    caretakers.add(trimmedCaretaker);
                }
            }
            if (caretakers.isEmpty()) {
                JOptionPane.showMessageDialog(this, "At least one caretaker is required.");
                return;
            }
            Item vehicle = new Item("Transport Truck", "VEH_001");
            vehicle.setPrice(vehiclePrice);
            Item fuel = new Item("Diesel Fuel", "FUEL_001");
            fuel.setPrice(fuelPrice);
            boolean success = zooService.moveAnimal(animalName, fromZoo, toZoo, vehicle, fuel, caretakers);
            if (success) {
                JOptionPane.showMessageDialog(this, "Animal '" + animalName + "' moved successfully from " + fromZoo + " to " + toZoo + " Zoo.");
                moveAnimalNameField.setText("");
                vehiclePriceField.setText("");
                fuelPriceField.setText("");
                caretakersField.setText("");
            } else {
                JOptionPane.showMessageDialog(this, "Failed to move animal. Check animal name or zoo capacity.");
            }
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "Invalid price format.");
        }
    });
    moveAnimalPanel.add(moveButton);
    operationsPanel.add(moveAnimalPanel);
    operationsPanel.add(Box.createVerticalStrut(10));

    // Remove Animal Section
    JPanel removeAnimalPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    removeAnimalPanel.setBorder(BorderFactory.createTitledBorder("Remove Animal"));
    JTextField removeAnimalNameField = new JTextField(10);
    removeAnimalPanel.add(new JLabel("Animal Name:"));
    removeAnimalPanel.add(removeAnimalNameField);
    JComboBox<String> removeZooComboBox = new JComboBox<>(new String[]{"Southern-Zone", "Northern-Zone"});
    removeAnimalPanel.add(new JLabel("Zoo:"));
    removeAnimalPanel.add(removeZooComboBox);
    JButton removeButton = new JButton("Remove");
    removeButton.addActionListener(e -> {
        String animalName = removeAnimalNameField.getText().trim();
        String zooName = (String) removeZooComboBox.getSelectedItem();
        if (animalName.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Animal name cannot be empty.");
            return;
        }
        boolean success = zooService.removeAnimal(zooName, animalName);
        if (success) {
            JOptionPane.showMessageDialog(this, "Animal '" + animalName + "' removed successfully from " + zooName + " Zoo.");
            removeAnimalNameField.setText("");
        } else {
            JOptionPane.showMessageDialog(this, "Failed to remove animal. Check animal name or zoo.");
        }
    });
    removeAnimalPanel.add(removeButton);
    operationsPanel.add(removeAnimalPanel);
    operationsPanel.add(Box.createVerticalStrut(10));

    // Find Animal Section
    JPanel findAnimalPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    findAnimalPanel.setBorder(BorderFactory.createTitledBorder("Find Animal"));
    JTextField findAnimalNameField = new JTextField(10);
    findAnimalPanel.add(new JLabel("Animal Name:"));
    findAnimalPanel.add(findAnimalNameField);
    JButton findButton = new JButton("Find");
    findButton.addActionListener(e -> {
        String animalName = findAnimalNameField.getText().trim();
        if (animalName.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Animal name cannot be empty.");
            return;
        }
        Animal animal = zooService.findAnimal(animalName);
        if (animal != null) {
            String zooName = zooService.getZoo("Southern-Zone").getAnimalByName(animalName) != null ? "Southern-Zone" : "Northern-Zone";
            JOptionPane.showMessageDialog(this, "Animal found in " + zooName + " Zoo:\nName: " + animal.getName() +
                    ", Species: " + animal.getSpecies() + ", Age: " + animal.getAge());
        } else {
            JOptionPane.showMessageDialog(this, "Animal '" + animalName + "' not found in either zoo.");
        }
    });
    findAnimalPanel.add(findButton);
    operationsPanel.add(findAnimalPanel);
    operationsPanel.add(Box.createVerticalStrut(10));

    // Display Animals Section
    JPanel displayAnimalsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    displayAnimalsPanel.setBorder(BorderFactory.createTitledBorder("Display Animals"));
    JComboBox<String> displayZooComboBox = new JComboBox<>(new String[]{"Southern-Zone", "Northern-Zone"});
    displayAnimalsPanel.add(new JLabel("Zoo:"));
    displayAnimalsPanel.add(displayZooComboBox);
    JTextArea displayArea = new JTextArea(5, 40);
    displayArea.setEditable(false);
    displayArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
    JScrollPane scrollPane = new JScrollPane(displayArea);
    JButton displayButton = new JButton("Display");
    displayButton.addActionListener(e -> {
        String zooName = (String) displayZooComboBox.getSelectedItem();
        if (zooName == null) {
            displayArea.setText("Error: No zoo selected.");
            return;
        }
        List<String> animals = zooService.displayAnimals(zooName);
        if (animals == null || animals.isEmpty()) {
            displayArea.setText("No animals available to display.");
            return;
        }
        StringBuilder sb = new StringBuilder();
        for (String info : animals) {
            sb.append(info).append("\n");
        }
        displayArea.setText(sb.toString());
    });
    displayAnimalsPanel.add(displayButton);
    operationsPanel.add(displayAnimalsPanel);
    operationsPanel.add(scrollPane);

    // Add the operation panel to the main content panel
    mainContentPanel.add(operationsPanel);

    // Add a new chart panel
    JPanel chartPanel = new JPanel(new BorderLayout());
    chartPanel.setBorder(BorderFactory.createTitledBorder("Zoo Animal Count Comparison"));

    // Create a chart
    JPanel chart = new JPanel() {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            // Obtain the number of animals in two zoos
            int southernCount = zooService.getAnimalCount("Southern-Zone");
            int northernCount = zooService.getAnimalCount("Northern-Zone");

            // Obtain the number of animals in two zoos
            int chartWidth = 300;
            int chartHeight = 200;
            int margin = 50;
            int barWidth = 80;

            // Draw the background
            g.setColor(Color.WHITE);
            g.fillRect(margin, margin, chartWidth, chartHeight);

            // Draw the coordinate axes
            g.setColor(Color.BLACK);
            g.drawLine(margin, margin, margin, margin + chartHeight);
            g.drawLine(margin, margin + chartHeight, margin + chartWidth, margin + chartHeight);

            // Calculate the maximum quantity for scaling
            int maxCount = Math.max(southernCount, northernCount);
            if (maxCount == 0) maxCount = 10;

            // Draw the bar chart
            int barHeight1 = (int)((double)southernCount / maxCount * chartHeight);
            int barHeight2 = (int)((double)northernCount / maxCount * chartHeight);

            // Bar chart of the Southern Zoo
            g.setColor(new Color(70, 130, 180)); // Steel blue
            g.fillRect(margin + 50, margin + chartHeight - barHeight1, barWidth, barHeight1);

            // Bar chart of the Northern Zoo
            g.setColor(new Color(220, 20, 60)); // Deep red
            g.fillRect(margin + 50 + barWidth + 30, margin + chartHeight - barHeight2, barWidth, barHeight2);

            // Draw labels
            g.setColor(Color.BLACK);
            g.drawString("Southern-Zone: " + southernCount, margin + 50, margin + chartHeight + 20);
            g.drawString("Northern-Zone: " + northernCount, margin + 50 + barWidth + 30, margin + chartHeight + 20);

            // Draw the scale on the Y-axis
            for (int i = 0; i <= maxCount; i += (maxCount > 10 ? maxCount/5 : 1)) {
                int y = margin + chartHeight - (int)((double)i / maxCount * chartHeight);
                g.drawString(String.valueOf(i), margin - 30, y + 5);
                g.drawLine(margin - 5, y, margin, y);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 300);
        }
    };

    // Add a refresh button
    JButton refreshButton = new JButton("Refresh Chart");
    refreshButton.addActionListener(e -> chart.repaint());

    JPanel buttonPanel = new JPanel();
    buttonPanel.add(refreshButton);

    chartPanel.add(chart, BorderLayout.CENTER);
    chartPanel.add(buttonPanel, BorderLayout.SOUTH);

    // Add the chart panel to the main content panel
    mainContentPanel.add(chartPanel);

    // Add the scroll bar
    JScrollPane mainScrollPane = new JScrollPane(mainContentPanel);
    panel.add(mainScrollPane, BorderLayout.CENTER);

    // Back button
    JButton backButton = new JButton("Back to Dashboard");
    backButton.addActionListener(e -> cardLayout.show(mainPanel, "dashboard"));
    JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    bottomPanel.add(backButton);
    panel.add(bottomPanel, BorderLayout.SOUTH);

    return panel;
}

    public static void main(String[] args) {
        SwingUtilities.invokeLater(GUI::new);
    }
}